From 1082d7ca4216fe413de43b262aa6bb1c90efb90a Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 12 Dec 2007 09:53:00 +0000 Subject: [PATCH] ioemu/qemu vga: save and restore vram buffer The existing stdvga driver from xen-unstable tools/ioemu/hw/vga* does not save the emulated VGA memory contents. The symptoms include video malfunction after restore, including black screen (which can often be fixed by asking the guest to redraw) but also missing font setup etc. The attached patch fixes this by saving the entire VGA memory buffer, just like the Xen ioemu Cirrus emulator does. I have reinterpreted the `is_vbe' byte, which is related to CONFIG_BOCHS_VBE, as a general flags word. This enables my code to allow old images to be restored (albeit with loss of VGA memory), by using another bit in that word to indicate whether the VGA memory dump is present. Signed-off-by: Ian Jackson --- tools/ioemu/hw/vga.c | 30 +++++++++++++++++++++--------- tools/ioemu/hw/vga_int.h | 3 +++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/tools/ioemu/hw/vga.c b/tools/ioemu/hw/vga.c index cb34f289fb..a1e2c09964 100644 --- a/tools/ioemu/hw/vga.c +++ b/tools/ioemu/hw/vga.c @@ -1742,6 +1742,8 @@ static CPUWriteMemoryFunc *vga_mem_write[3] = { static void vga_save(QEMUFile *f, void *opaque) { VGAState *s = opaque; + unsigned save_format_flags; + uint32_t vram_size; #ifdef CONFIG_BOCHS_VBE int i; #endif @@ -1772,8 +1774,9 @@ static void vga_save(QEMUFile *f, void *opaque) qemu_put_buffer(f, s->palette, 768); qemu_put_be32s(f, &s->bank_offset); + save_format_flags = VGA_SAVE_FORMAT_FLAG_VRAM_DATA; #ifdef CONFIG_BOCHS_VBE - qemu_put_byte(f, 1); + qemu_put_byte(f, save_format_flags | VGA_SAVE_FORMAT_FLAG_BOCHS_VBE); qemu_put_be16s(f, &s->vbe_index); for(i = 0; i < VBE_DISPI_INDEX_NB; i++) qemu_put_be16s(f, &s->vbe_regs[i]); @@ -1781,17 +1784,19 @@ static void vga_save(QEMUFile *f, void *opaque) qemu_put_be32s(f, &s->vbe_line_offset); qemu_put_be32s(f, &s->vbe_bank_mask); #else - qemu_put_byte(f, 0); + qemu_put_byte(f, save_format_flags); #endif + vram_size = s->vram_size; + qemu_put_be32s(f, &vram_size); + qemu_put_buffer(f, s->vram_ptr, s->vram_size); } static int vga_load(QEMUFile *f, void *opaque, int version_id) { VGAState *s = opaque; - int is_vbe, ret; -#ifdef CONFIG_BOCHS_VBE - int i; -#endif + int ret; + unsigned int save_format_flags; + uint32_t vram_size; if (version_id > 2) return -EINVAL; @@ -1825,9 +1830,9 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id) qemu_get_buffer(f, s->palette, 768); qemu_get_be32s(f, &s->bank_offset); - is_vbe = qemu_get_byte(f); + save_format_flags = qemu_get_byte(f); #ifdef CONFIG_BOCHS_VBE - if (!is_vbe) + if (!(save_format_flags & VGA_SAVE_FORMAT_FLAG_BOCHS_VBE)) return -EINVAL; qemu_get_be16s(f, &s->vbe_index); for(i = 0; i < VBE_DISPI_INDEX_NB; i++) @@ -1836,9 +1841,16 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be32s(f, &s->vbe_line_offset); qemu_get_be32s(f, &s->vbe_bank_mask); #else - if (is_vbe) + if (save_format_flags & VGA_SAVE_FORMAT_FLAG_BOCHS_VBE) return -EINVAL; #endif + if (save_format_flags & VGA_SAVE_FORMAT_FLAG_VRAM_DATA) { + /* people who restore old images may be lucky ... */ + qemu_get_be32s(f, &vram_size); + if (vram_size != s->vram_size) + return -EINVAL; + qemu_get_buffer(f, s->vram_ptr, s->vram_size); + } /* force refresh */ s->graphic_mode = -1; diff --git a/tools/ioemu/hw/vga_int.h b/tools/ioemu/hw/vga_int.h index 3dd9330573..7c870d8d18 100644 --- a/tools/ioemu/hw/vga_int.h +++ b/tools/ioemu/hw/vga_int.h @@ -157,6 +157,9 @@ static inline int c6_to_8(int v) return (v << 2) | (b << 1) | b; } +#define VGA_SAVE_FORMAT_FLAG_BOCHS_VBE 0x01 +#define VGA_SAVE_FORMAT_FLAG_VRAM_DATA 0x02 + void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, unsigned long vga_ram_offset, int vga_ram_size); uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr); -- 2.30.2